﻿//using System;
//using System.Collections;
//using System.Collections.Generic;
//#if !SILVERLIGHT
//using System.Data;
//#endif
//using System.Globalization;
//using System.IO;
//using System.Reflection;
//using System.Reflection.Emit;

//namespace Framework.Serializer.FastJson
//{
//    public delegate string Serialize(object data);
//    public delegate object Deserialize(string data);

//    public sealed class JSONParameters
//    {
//        /// <summary>
//        /// Use the optimized fast Dataset Schema format (dfault = True)
//        /// </summary>
//        public bool UseOptimizedDatasetSchema = true;
//        /// <summary>
//        /// Use the fast GUID format (default = True)
//        /// </summary>
//        public bool UseFastGuid = true;
//        /// <summary>
//        /// Serialize null values to the output (default = True)
//        /// </summary>
//        public bool SerializeNullValues = true;
//        /// <summary>
//        /// Use the UTC date format (default = True)
//        /// </summary>
//        public bool UseUTCDateTime = true;
//        /// <summary>
//        /// Show the readonly properties of types in the output (default = False)
//        /// </summary>
//        public bool ShowReadOnlyProperties = false;
//        /// <summary>
//        /// Use the $types extension to optimise the output json (default = True)
//        /// </summary>
//        public bool UsingGlobalTypes = true;
//        /// <summary>
//        /// ** work in progress
//        /// </summary>
//        public bool IgnoreCaseOnDeserialize = false;
//        /// <summary>
//        /// Anonymous types have read only properties 
//        /// </summary>
//        public bool EnableAnonymousTypes = false;
//        /// <summary>
//        /// Enable fastJSON extensions $types, $type, $map (default = True)
//        /// </summary>
//        public bool UseExtensions = true;

//        public void FixValues()
//        {
//            if (UseExtensions == false) // disable conflicting params
//            {
//                UsingGlobalTypes = false;
//            }
//        }
//    }

//    public sealed class JSON
//    {
//        //public readonly static JSON Instance = new JSON();
//        [ThreadStatic]
//        private static JSON _instance;

//        public static JSON Instance
//        {
//            get { return _instance ?? (_instance = new JSON()); }
//        }

//        private JSON()
//        {
//        }
//        /// <summary>
//        /// You can set these paramters globally for all calls
//        /// </summary>
//        public JSONParameters Parameters = new JSONParameters();
//        private JSONParameters _params;

//        public string ToJSON(object obj)
//        {
//            _params = Parameters;
//            _params.FixValues();
//            Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
//            return ToJSON(obj, Parameters);
//        }

//        public string ToJSON(object obj, JSONParameters param)
//        {
//            _params = param;
//            _params.FixValues();
//            Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
//            Type t = null;

//            if (obj == null)
//                return "null";

//            if (obj.GetType().IsGenericType)
//                t = obj.GetType().GetGenericTypeDefinition();
//            if (t == typeof(Dictionary<,>) || t == typeof(List<>))
//                _params.UsingGlobalTypes = false;

//            // FEATURE : enable extensions when you can deserialize anon types
//            if (_params.EnableAnonymousTypes) { _params.UseExtensions = false; _params.UsingGlobalTypes = false; Reflection.Instance.ShowReadOnlyProperties = true; }
//            _usingglobals = _params.UsingGlobalTypes;
//            return new JSONSerializer(_params).ConvertToJSON(obj);
//        }

//        public object Parse(string json)
//        {
//            _params = Parameters;
//            Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
//            return new JsonParser(json, _params.IgnoreCaseOnDeserialize).Decode();
//        }

//        public T ToObject<T>(string json)
//        {
//            return (T)ToObject(json, typeof(T));
//        }

//        public object ToObject(string json)
//        {
//            return ToObject(json, null);
//        }

//        public object ToObject(string json, Type type)
//        {
//            _params = Parameters;
//            _params.FixValues();
//            Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
//            Type t = null;
//            if (type != null && type.IsGenericType)
//                t = type.GetGenericTypeDefinition();
//            if (t == typeof(Dictionary<,>) || t == typeof(List<>))
//                _params.UsingGlobalTypes = false;
//            _usingglobals = _params.UsingGlobalTypes;

//            object o = new JsonParser(json, Parameters.IgnoreCaseOnDeserialize).Decode();
//#if !SILVERLIGHT
//            if (type != null && type == typeof(DataSet))
//                return CreateDataset(o as Dictionary<string, object>, null);

//            if (type != null && type == typeof(DataTable))
//                return CreateDataTable(o as Dictionary<string, object>, null);
//#endif
//            if (o is IDictionary)
//            {
//                if (type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) // deserialize a dictionary
//                    return RootDictionary(o, type);
//                else // deserialize an object
//                    return ParseDictionary(o as Dictionary<string, object>, null, type, null);
//            }

//            if (o is List<object>)
//            {
//                if (type != null && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) // kv format
//                    return RootDictionary(o, type);

//                if (type != null && type.GetGenericTypeDefinition() == typeof(List<>)) // deserialize to generic list
//                    return RootList(o, type);
//                else
//                    return (o as List<object>).ToArray();
//            }
            
//            if (type!=null && o.GetType() != type)
//                return ChangeType(o, type);

//            return o;
//        }

//        public string Beautify(string input)
//        {
//            return Formatter.PrettyPrint(input);
//        }

//        public object FillObject(object input, string json)
//        {
//            _params = Parameters;
//            _params.FixValues();
//            Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties;
//            Dictionary<string, object> ht = new JsonParser(json, Parameters.IgnoreCaseOnDeserialize).Decode() as Dictionary<string, object>;
//            if (ht == null) return null;
//            return ParseDictionary(ht, null, input.GetType(), input);
//        }

//        public object DeepCopy(object obj)
//        {
//            return ToObject(ToJSON(obj));
//        }

//        public T DeepCopy<T>(T obj)
//        {
//            return ToObject<T>(ToJSON(obj));
//        }

//#if CUSTOMTYPE
//        internal SafeDictionary<Type, Serialize> _customSerializer = new SafeDictionary<Type, Serialize>();
//        internal SafeDictionary<Type, Deserialize> _customDeserializer = new SafeDictionary<Type, Deserialize>();

//        public void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer)
//        {
//            if (type != null && serializer != null && deserializer != null)
//            {
//                _customSerializer.Add(type, serializer);
//                _customDeserializer.Add(type, deserializer);
//                // reset property cache
//                _propertycache = new SafeDictionary<string, SafeDictionary<string, myPropInfo>>();
//            }
//        }

//        internal bool IsTypeRegistered(Type t)
//        {
//            Serialize s;
//            return _customSerializer.TryGetValue(t, out s);
//        }
//#endif

//        #region [   JSON specific reflection   ]

//        private struct myPropInfo
//        {
//            public bool filled;
//            public Type pt;
//            public Type bt;
//            public Type changeType;
//            public bool isDictionary;
//            public bool isValueType;
//            public bool isGenericType;
//            public bool isArray;
//            public bool isByteArray;
//            public bool isGuid;
//#if !SILVERLIGHT
//            public bool isDataSet;
//            public bool isDataTable;
//            public bool isHashtable;
//#endif
//            public Reflection.GenericSetter setter;
//            public bool isEnum;
//            public bool isDateTime;
//            public Type[] GenericTypes;
//            public bool isInt;
//            public bool isLong;
//            public bool isString;
//            public bool isBool;
//            public bool isClass;
//            public Reflection.GenericGetter getter;
//            public bool isStringDictionary;
//            public string Name;
//#if CUSTOMTYPE
//            public bool isCustomType;
//#endif
//            public bool CanWrite;
//        }

//        SafeDictionary<string, SafeDictionary<string, myPropInfo>> _propertycache = new SafeDictionary<string, SafeDictionary<string, myPropInfo>>();
//        private SafeDictionary<string, myPropInfo> Getproperties(Type type, string typename)
//        {
//            SafeDictionary<string, myPropInfo> sd = null;
//            if (_propertycache.TryGetValue(typename, out sd))
//            {
//                return sd;
//            }
//            else
//            {
//                sd = new SafeDictionary<string, myPropInfo>();
//                PropertyInfo[] pr = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
//                foreach (PropertyInfo p in pr)
//                {
//                    myPropInfo d = CreateMyProp(p.PropertyType, p.Name);
//                    d.CanWrite = p.CanWrite;
//                    d.setter = Reflection.CreateSetMethod(type, p);
//                    d.getter = Reflection.CreateGetMethod(type, p);
//                    sd.Add(p.Name, d);
//                }
//                FieldInfo[] fi = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
//                foreach (FieldInfo f in fi)
//                {
//                    myPropInfo d = CreateMyProp(f.FieldType, f.Name);
//                    d.setter = Reflection.CreateSetField(type, f);
//                    d.getter = Reflection.CreateGetField(type, f);
//                    sd.Add(f.Name, d);
//                }

//                _propertycache.Add(typename, sd);
//                return sd;
//            }
//        }

//        private myPropInfo CreateMyProp(Type t, string name)
//        {
//            myPropInfo d = new myPropInfo();
//            d.filled = true;
//            d.CanWrite = true;
//            d.pt = t;
//            d.Name = name;
//            d.isDictionary = t.Name.Contains("Dictionary");
//            if (d.isDictionary)
//                d.GenericTypes = t.GetGenericArguments();
//            d.isValueType = t.IsValueType;
//            d.isGenericType = t.IsGenericType;
//            d.isArray = t.IsArray;
//            if (d.isArray)
//                d.bt = t.GetElementType();
//            if (d.isGenericType)
//                d.bt = t.GetGenericArguments()[0];
//            d.isByteArray = t == typeof(byte[]);
//            d.isGuid = (t == typeof(Guid) || t == typeof(Guid?));
//#if !SILVERLIGHT
//            d.isHashtable = t == typeof(Hashtable);
//            d.isDataSet = t == typeof(DataSet);
//            d.isDataTable = t == typeof(DataTable);
//#endif

//            d.changeType = GetChangeType(t);
//            d.isEnum = t.IsEnum;
//            d.isDateTime = t == typeof(DateTime) || t == typeof(DateTime?);
//            d.isInt = t == typeof(int) || t == typeof(int?);
//            d.isLong = t == typeof(long) || t == typeof(long?);
//            d.isString = t == typeof(string);
//            d.isBool = t == typeof(bool) || t == typeof(bool?);
//            d.isClass = t.IsClass;

//            if (d.isDictionary && d.GenericTypes.Length > 0 && d.GenericTypes[0] == typeof(string))
//                d.isStringDictionary = true;

//#if CUSTOMTYPE
//            if (IsTypeRegistered(t))
//                d.isCustomType = true;
//#endif
//            return d;
//        }

//        private object ChangeType(object value, Type conversionType)
//        {
//            if (conversionType == typeof(int))
//                return (int)((long)value);

//            else if (conversionType == typeof(long))
//                return (long)value;

//            else if (conversionType == typeof(string))
//                return (string)value;

//            else if (conversionType == typeof(Guid))
//                return CreateGuid((string)value);

//            else if (conversionType.IsEnum)
//                return CreateEnum(conversionType, (string)value);

//            return Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture);
//        }
//        #endregion

//        #region [   p r i v a t e   m e t h o d s   ]

//        private object RootList(object parse, Type type)
//        {
//            Type[] gtypes = type.GetGenericArguments();
//            IList o = (IList)Reflection.Instance.FastCreateInstance(type);
//            foreach (var k in (IList)parse)
//            {
//                _usingglobals = false;
//                object v = k;
//                if (k is Dictionary<string, object>)
//                    v = ParseDictionary(k as Dictionary<string, object>, null, gtypes[0], null);
//                else
//                    v = ChangeType(k, gtypes[0]);

//                o.Add(v);
//            }
//            return o;
//        }

//        private object RootDictionary(object parse, Type type)
//        {
//            Type[] gtypes = type.GetGenericArguments();
//            if (parse is Dictionary<string, object>)
//            {
//                IDictionary o = (IDictionary)Reflection.Instance.FastCreateInstance(type);

//                foreach (var kv in (Dictionary<string, object>)parse)
//                {
//                    object v;
//                    object k = ChangeType(kv.Key, gtypes[0]);
//                    if (kv.Value is Dictionary<string, object>)
//                        v = ParseDictionary(kv.Value as Dictionary<string, object>, null, gtypes[1], null);
//                    else if (kv.Value is List<object>)
//                        v = CreateArray(kv.Value as List<object>, typeof(object), typeof(object), null);
//                    else
//                        v = ChangeType(kv.Value, gtypes[1]);
//                    o.Add(k, v);
//                }

//                return o;
//            }
//            if (parse is List<object>)
//                return CreateDictionary(parse as List<object>, type, gtypes, null);

//            return null;
//        }

//        bool _usingglobals = false;
//        private object ParseDictionary(Dictionary<string, object> d, Dictionary<string, object> globaltypes, Type type, object input)
//        {
//            object tn = "";

//            if (d.TryGetValue("$types", out tn))
//            {
//                _usingglobals = true;
//                globaltypes = new Dictionary<string, object>();
//                foreach (var kv in (Dictionary<string, object>)tn)
//                {
//                    globaltypes.Add((string)kv.Value, kv.Key);
//                }
//            }

//            bool found = d.TryGetValue("$type", out tn);
//#if !SILVERLIGHT
//            if (found == false && type == typeof(System.Object))
//            {
//                return CreateDataset(d, globaltypes);
//            }
//#endif
//            if (found)
//            {
//                if (_usingglobals)
//                {
//                    object tname = "";
//                    if (globaltypes.TryGetValue((string)tn, out tname))
//                        tn = tname;
//                }
//                type = Reflection.Instance.GetTypeFromCache((string)tn);
//            }

//            if (type == null)
//                throw new Exception("Cannot determine type");

//            string typename = type.FullName;
//            object o = input;
//            if (o == null)
//                o = Reflection.Instance.FastCreateInstance(type);

//            SafeDictionary<string, myPropInfo> props = Getproperties(type, typename);
//            foreach (string n in d.Keys)
//            {
//                string name = n;
//                if (_params.IgnoreCaseOnDeserialize) name = name.ToLower();
//                if (name == "$map")
//                {
//                    ProcessMap(o, props, (Dictionary<string, object>)d[name]);
//                    continue;
//                }
//                myPropInfo pi;
//                if (props.TryGetValue(name, out pi) == false)
//                    continue;
//                if (pi.filled && pi.CanWrite)
//                {
//                    object v = d[name];

//                    if (v != null)
//                    {
//                        object oset = null;

//                        if (pi.isInt)
//                            oset = (int)((long)v);
//#if CUSTOMTYPE
//                        else if (pi.isCustomType)
//                            oset = CreateCustom((string)v, pi.pt);
//#endif
//                        else if (pi.isLong)
//                            oset = (long)v;

//                        else if (pi.isString)
//                            oset = (string)v;

//                        else if (pi.isBool)
//                            oset = (bool)v;

//                        else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false)
//                            oset = CreateGenericList((List<object>)v, pi.pt, pi.bt, globaltypes);

//                        else if (pi.isByteArray)
//                            oset = Convert.FromBase64String((string)v);

//                        else if (pi.isArray && pi.isValueType == false)
//                            oset = CreateArray((List<object>)v, pi.pt, pi.bt, globaltypes);

//                        else if (pi.isGuid)
//                            oset = CreateGuid((string)v);
//#if !SILVERLIGHT
//                        else if (pi.isDataSet)
//                            oset = CreateDataset((Dictionary<string, object>)v, globaltypes);

//                        else if (pi.isDataTable)
//                            oset = this.CreateDataTable((Dictionary<string, object>)v, globaltypes);
//#endif

//                        else if (pi.isStringDictionary)
//                            oset = CreateStringKeyDictionary((Dictionary<string, object>)v, pi.pt, pi.GenericTypes, globaltypes);
//#if !SILVERLIGHT
//                        else if (pi.isDictionary || pi.isHashtable)
//#else
//                        else if (pi.isDictionary)
//#endif
//                            oset = CreateDictionary((List<object>)v, pi.pt, pi.GenericTypes, globaltypes);

//                        else if (pi.isEnum)
//                            oset = CreateEnum(pi.pt, (string)v);

//                        else if (pi.isDateTime)
//                            oset = CreateDateTime((string)v);

//                        else if (pi.isClass && v is Dictionary<string, object>)
//                            oset = ParseDictionary((Dictionary<string, object>)v, globaltypes, pi.pt, pi.getter(o));

//                        else if (pi.isValueType)
//                            oset = ChangeType(v, pi.changeType);

//                        else if (v is List<object>)
//                            oset = CreateArray((List<object>)v, pi.pt, typeof(object), globaltypes);

//                        else
//                            oset = v;

//                        o = pi.setter(o, oset);
//                    }
//                }
//            }
//            return o;
//        }

//#if CUSTOMTYPE
//        private object CreateCustom(string v, Type type)
//        {
//            Deserialize d;
//            _customDeserializer.TryGetValue(type, out d);
//            return d(v);
//        }
//#endif

//        private void ProcessMap(object obj, SafeDictionary<string, JSON.myPropInfo> props, Dictionary<string, object> dic)
//        {
//            foreach (KeyValuePair<string, object> kv in dic)
//            {
//                myPropInfo p = props[kv.Key];
//                object o = p.getter(obj);
//                Type t = Type.GetType((string)kv.Value);
//                if (t == typeof(Guid))
//                    p.setter(obj, CreateGuid((string)o));
//            }
//        }

//        private long CreateLong(string s)
//        {
//            long num = 0;
//            bool neg = false;
//            foreach (char cc in s)
//            {
//                if (cc == '-')
//                    neg = true;
//                else if (cc == '+')
//                    neg = false;
//                else
//                {
//                    num *= 10;
//                    num += (int)(cc - '0');
//                }
//            }

//            return neg ? -num : num;
//        }

//        private object CreateEnum(Type pt, string v)
//        {
//            // TODO : optimize create enum
//#if !SILVERLIGHT
//            return Enum.Parse(pt, v);
//#else
//            return Enum.Parse(pt, v, true);
//#endif
//        }

//        private Guid CreateGuid(string s)
//        {
//            if (s.Length > 30)
//                return new Guid(s);
//            else
//                return new Guid(Convert.FromBase64String(s));
//        }

//        private DateTime CreateDateTime(string value)
//        {
//            bool utc = false;
//            //                   0123456789012345678
//            // datetime format = yyyy-MM-dd HH:mm:ss
//            int year = (int)CreateLong(value.Substring(0, 4));
//            int month = (int)CreateLong(value.Substring(5, 2));
//            int day = (int)CreateLong(value.Substring(8, 2));
//            int hour = (int)CreateLong(value.Substring(11, 2));
//            int min = (int)CreateLong(value.Substring(14, 2));
//            int sec = (int)CreateLong(value.Substring(17, 2));

//            if (value.EndsWith("Z"))
//                utc = true;

//            if (_params.UseUTCDateTime == false && utc == false)
//                return new DateTime(year, month, day, hour, min, sec);
//            else
//                return new DateTime(year, month, day, hour, min, sec, DateTimeKind.Utc).ToLocalTime();
//        }

//        private object CreateArray(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes)
//        {
//            Array col = Array.CreateInstance(bt, data.Count);
//            // create an array of objects
//            for (int i = 0; i < data.Count; i++)// each (object ob in data)
//            {
//                object ob = data[i];
//                if (ob is IDictionary)
//                    col.SetValue(ParseDictionary((Dictionary<string, object>)ob, globalTypes, bt, null), i);
//                else
//                    col.SetValue(ChangeType(ob, bt), i);
//            }

//            return col;
//        }


//        private object CreateGenericList(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes)
//        {
//            IList col = (IList)Reflection.Instance.FastCreateInstance(pt);
//            // create an array of objects
//            foreach (object ob in data)
//            {
//                if (ob is IDictionary)
//                    col.Add(ParseDictionary((Dictionary<string, object>)ob, globalTypes, bt, null));

//                else if (ob is List<object>)
//                    col.Add(((List<object>)ob).ToArray());

//                else
//                    col.Add(ChangeType(ob, bt));
//            }
//            return col;
//        }

//        private object CreateStringKeyDictionary(Dictionary<string, object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes)
//        {
//            var col = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
//            Type t1 = null;
//            Type t2 = null;
//            if (types != null)
//            {
//                t1 = types[0];
//                t2 = types[1];
//            }

//            foreach (KeyValuePair<string, object> values in reader)
//            {
//                var key = values.Key;//ChangeType(values.Key, t1);
//                object val = null;
//                if (values.Value is Dictionary<string, object>)
//                    val = ParseDictionary((Dictionary<string, object>)values.Value, globalTypes, t2, null);
//                else
//                    val = ChangeType(values.Value, t2);
//                col.Add(key, val);
//            }

//            return col;
//        }

//        private object CreateDictionary(List<object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes)
//        {
//            IDictionary col = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
//            Type t1 = null;
//            Type t2 = null;
//            if (types != null)
//            {
//                t1 = types[0];
//                t2 = types[1];
//            }

//            foreach (Dictionary<string, object> values in reader)
//            {
//                object key = values["k"];
//                object val = values["v"];

//                if (key is Dictionary<string, object>)
//                    key = ParseDictionary((Dictionary<string, object>)key, globalTypes, t1, null);
//                else
//                    key = ChangeType(key, t1);

//                if (val is Dictionary<string, object>)
//                    val = ParseDictionary((Dictionary<string, object>)val, globalTypes, t2, null);
//                else
//                    val = ChangeType(val, t2);

//                col.Add(key, val);
//            }

//            return col;
//        }

//        private Type GetChangeType(Type conversionType)
//        {
//            if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
//                return conversionType.GetGenericArguments()[0];

//            return conversionType;
//        }
//#if !SILVERLIGHT
//        private DataSet CreateDataset(Dictionary<string, object> reader, Dictionary<string, object> globalTypes)
//        {
//            DataSet ds = new DataSet();
//            ds.EnforceConstraints = false;
//            ds.BeginInit();

//            // read dataset schema here
//            ReadSchema(reader, ds, globalTypes);

//            foreach (KeyValuePair<string, object> pair in reader)
//            {
//                if (pair.Key == "$type" || pair.Key == "$schema") continue;

//                List<object> rows = (List<object>)pair.Value;
//                if (rows == null) continue;

//                DataTable dt = ds.Tables[pair.Key];
//                ReadDataTable(rows, dt);
//            }

//            ds.EndInit();

//            return ds;
//        }

//        private void ReadSchema(Dictionary<string, object> reader, DataSet ds, Dictionary<string, object> globalTypes)
//        {
//            var schema = reader["$schema"];

//            if (schema is string)
//            {
//                TextReader tr = new StringReader((string)schema);
//                ds.ReadXmlSchema(tr);
//            }
//            else
//            {
//                DatasetSchema ms = (DatasetSchema)ParseDictionary((Dictionary<string, object>)schema, globalTypes, typeof(DatasetSchema), null);
//                ds.DataSetName = ms.Name;
//                for (int i = 0; i < ms.Info.Count; i += 3)
//                {
//                    if (ds.Tables.Contains(ms.Info[i]) == false)
//                        ds.Tables.Add(ms.Info[i]);
//                    ds.Tables[ms.Info[i]].Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2]));
//                }
//            }
//        }

//        private void ReadDataTable(List<object> rows, DataTable dt)
//        {
//            dt.BeginInit();
//            dt.BeginLoadData();
//            List<int> guidcols = new List<int>();
//            List<int> datecol = new List<int>();

//            foreach (DataColumn c in dt.Columns)
//            {
//                if (c.DataType == typeof(Guid) || c.DataType == typeof(Guid?))
//                    guidcols.Add(c.Ordinal);
//                if (_params.UseUTCDateTime && (c.DataType == typeof(DateTime) || c.DataType == typeof(DateTime?)))
//                    datecol.Add(c.Ordinal);
//            }

//            foreach (List<object> row in rows)
//            {
//                object[] v = new object[row.Count];
//                row.CopyTo(v, 0);
//                foreach (int i in guidcols)
//                {
//                    string s = (string)v[i];
//                    if (s != null && s.Length < 36)
//                        v[i] = new Guid(Convert.FromBase64String(s));
//                }
//                if (_params.UseUTCDateTime)
//                {
//                    foreach (int i in datecol)
//                    {
//                        string s = (string)v[i];
//                        if (s != null)
//                            v[i] = CreateDateTime(s);
//                    }
//                }
//                dt.Rows.Add(v);
//            }

//            dt.EndLoadData();
//            dt.EndInit();
//        }

//        DataTable CreateDataTable(Dictionary<string, object> reader, Dictionary<string, object> globalTypes)
//        {
//            var dt = new DataTable();

//            // read dataset schema here
//            var schema = reader["$schema"];

//            if (schema is string)
//            {
//                TextReader tr = new StringReader((string)schema);
//                dt.ReadXmlSchema(tr);
//            }
//            else
//            {
//                var ms = (DatasetSchema)this.ParseDictionary((Dictionary<string, object>)schema, globalTypes, typeof(DatasetSchema), null);
//                dt.TableName = ms.Info[0];
//                for (int i = 0; i < ms.Info.Count; i += 3)
//                {
//                    dt.Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2]));
//                }
//            }

//            foreach (var pair in reader)
//            {
//                if (pair.Key == "$type" || pair.Key == "$schema")
//                    continue;

//                var rows = (List<object>)pair.Value;
//                if (rows == null)
//                    continue;

//                if (!dt.TableName.Equals(pair.Key, StringComparison.InvariantCultureIgnoreCase))
//                    continue;

//                ReadDataTable(rows, dt);
//            }

//            return dt;
//        }
//#endif
//        #endregion
//    }

//}